﻿using System;
using System.Collections.Generic;
#if DEBUG
using System.Diagnostics;
#endif // #if DEBUG
using System.IO;
using System.Linq;
using System.Text;
using System.Data.Objects.DataClasses;

using FRL.DebtChased.Extensions;
using FRL.DebtChased.WebServices;
using FRL.DebtChased.Repository.ViewModels;

namespace FRL.DebtChased.Repository
{

	/// <summary>
	/// Extensions to the CommTemplate model
	/// </summary>
	public partial class CommTemplate
	{

		/////////////////////////////////////////////////////////////
		// Attributes

		public Definitions.eCommTemplateType TemplateType
		{
			get { return (Definitions.eCommTemplateType)this._fdTemplateType; }
			set { this.fdTemplateType = (int)value; }
		}

		/////////////////////////////////////////////////////////////////
		// Static Operations

		public static Dictionary<int, string> LoadDictionary(DebtChasedEntities ent, Definitions.eCommTemplateType TemplateType)
		{

			// Declare return variable
			Dictionary<int, string> Ftmp = new Dictionary<int,string>();

			// Load templates for format
			var results = from t in ent.CommTemplates
						  where (t.fdTemplateType == (int)TemplateType)
						  select new { Key = t.CommTemplateId, Value = t.Name };

			// Load the dictonary
			foreach (var ob in results)
				Ftmp.Add(ob.Key, ob.Value);

			// Return variable
			return Ftmp;

		}

		public static List<CommTemplateTransport> LoadTransportList(DebtChasedEntities ent)
		{

			// Declare return variable
			List<CommTemplateTransport> Ftmp = new List<CommTemplateTransport>();

			// Load from table
			var results = from ct in ent.CommTemplates
						  select new { ct.CommTemplateId, ct.Name, ct.fdTemplateType };
			foreach (var result in results)
			{
				Ftmp.Add( new CommTemplateTransport()
				{ 
					CommTemplateId = result.CommTemplateId,
					CommTemplateType = result.fdTemplateType,
					Name = result.Name					 
				});
			}

			// Return variable
			return Ftmp;

		}

		public static string Clone(DebtChasedEntities ent, int iCommTemplateId, string strTemplateFolderPath, int iUserId)
		{

			// Declare return variable
			string strError = null;

			try
			{

				// Lock the record
				strError = RecentActivity.AttemptLock(ent, "tbCommTemplate", iCommTemplateId, iUserId);
				if (strError == null)
				{

					// Load the comm template record
					var commTemplate = (from ct in ent.CommTemplates
										where (ct.CommTemplateId == iCommTemplateId)
										select ct).FirstOrDefault();

					// Compose a unique new name
					List<string> strTemplateNames = (from ct in ent.CommTemplates select ct.Name).ToList();
					string strNewName = commTemplate.Name.ComposeCopyName(strTemplateNames);

					// Compare types
					CommTemplate newCommTemplate = null;
					if (commTemplate.TemplateType == Definitions.eCommTemplateType.Email)
					{

						// Compose a duplicate template
						newCommTemplate = CommTemplate.CreateCommTemplate(0, commTemplate.fdTemplateType, strNewName);
						newCommTemplate.Body = commTemplate.Body;
						newCommTemplate.SummaryLine = commTemplate.SummaryLine;
						ent.CommTemplates.AddObject(newCommTemplate);

					}
					else
					{

						// Duplicate the word file
						string strSourceFilepath = Path.Combine(strTemplateFolderPath, commTemplate.Filename);
						string strFilename = CommTemplate.ComposeNewTemplateFilename(Path.GetExtension(commTemplate.Filename));
						string strTargetFilepath = Path.Combine(strTemplateFolderPath, strFilename);
						File.Copy(strSourceFilepath, strTargetFilepath);

						// Compose a duplicate template
						newCommTemplate = CommTemplate.CreateCommTemplate(0, commTemplate.fdTemplateType, strNewName);
						newCommTemplate.Filename = strFilename;
						newCommTemplate.SummaryLine = commTemplate.SummaryLine;
						ent.CommTemplates.AddObject(newCommTemplate);

					}

					// User action session
					UserAction.Session session = new UserAction.Session(iUserId, newCommTemplate, strNewName);

					// Save changes
					ent.SaveChanges();

					// Save user actions
					session.SaveChanges(ent);

				}

			}
			catch (Exception x)
			{

				// Process exception
				strError = ErrorProcessing.HandleException(x, "clone template", iUserId);

			}

			// Return variable
			return strError;

		}

		public static string Delete(DebtChasedEntities ent, int iCommTemplateId, string strTemplateFolderPath, int iUserId)
		{

			// Declare return variable
			string strError = null;

			try
			{

				// Lock the record
				strError = RecentActivity.AttemptLock(ent, "tbCommTemplate", iCommTemplateId, iUserId);
				if (strError == null)
				{

					// Load the comm template record
					var commTemplate = (from ct in ent.CommTemplates
										where (ct.CommTemplateId == iCommTemplateId)
										select ct).FirstOrDefault();

					// User action session
					UserAction.Session session = new UserAction.Session(iUserId, commTemplate, commTemplate.Name);

					// Delete the comm template
					ent.CommTemplates.DeleteObject(commTemplate);

					// If there is a file...
					if (commTemplate.TemplateType == Definitions.eCommTemplateType.Letter)
					{

						// Get the filepath
						string strTemplateFilepath = Path.Combine(strTemplateFolderPath, commTemplate.Filename);
						if (File.Exists(strTemplateFilepath))
							File.Delete(strTemplateFilepath);

					}

					// Save changes
					ent.SaveChanges();

					// Save user actions
					session.SaveChanges(ent);

				}

			}
			catch (Exception x)
			{

				// Process exception
				strError = ErrorProcessing.HandleException(x, "delete template", iUserId);

			}

			// Return variable
			return strError;

		}

		public static Definitions.eCommTemplateType GetTemplateType(DebtChasedEntities ent, int iCommTemplateId)
		{

			// Load type from repository
			Definitions.eCommTemplateType Ftmp = (Definitions.eCommTemplateType)(from ct in ent.CommTemplates
												   where (ct.CommTemplateId == iCommTemplateId)
												   select ct.fdTemplateType).First();

			// Return variable
			return Ftmp;

		}

		public static bool GetEmailTemplate(DebtChasedEntities ent, int iCommTemplateId, out string strBody)
		{

			// Declare return variable
			bool bFtmp = true;

			// Reset function parameters
			strBody = null;

			// Load template details
			var template = (from ct in ent.CommTemplates
						   where ct.CommTemplateId == iCommTemplateId
						   select new { ct.fdTemplateType,ct.Body}).FirstOrDefault();

			// If template found...
			if (template != null)
			{

				// Check the template type
				if (template.fdTemplateType == (int)Definitions.eCommTemplateType.Email)
				{

					// Update return variable
					strBody = template.Body;

				}
				else
				{
#if DEBUG
					Debug.Assert(false);
#endif // #if DEBUG
					bFtmp = false;
				}

			}
			else
			{
#if DEBUG
				Debug.Assert(false);
#endif // #if DEBUG
				bFtmp = false;
			}

			// Return variable
			return bFtmp;

		}

		public static void Get(
			DebtChasedEntities ent,
			int iCommTemplateId,
			out string strName,
			out Definitions.eCommTemplateType TemplateType,
			out string strBody
		)
		{

			// Load details from repository
			var result = (from ct in ent.CommTemplates
						  where ct.CommTemplateId == iCommTemplateId
						  select new { ct.fdTemplateType, ct.Name, ct.Body }).First();

			// Update function parameters
			strName = result.Name;
			TemplateType = (Definitions.eCommTemplateType) result.fdTemplateType;
			strBody = result.Body;

		}

		public static void Get(
			DebtChasedEntities ent,
			int iCommTemplateId,
			out string strName,
			out string strFilename
		)
		{

			// Load details from repository
			var result = (from ct in ent.CommTemplates
						  where ct.CommTemplateId == iCommTemplateId
						  select new { ct.Name, ct.Filename }).First();

			// Update function parameters
			strName = result.Name;
			strFilename = result.Filename;

		}

		public static string Set( DebtChasedEntities ent,int iCommTemplateId, Definitions.eCommTemplateType templateType, string strName, string strBody, int iUserId )
		{

			// Declare return variable
			string strError = null;

			try
			{

				// If this is a new template...
				CommTemplate commTemplate = null;
				if (iCommTemplateId == 0)
				{

					// Create the comm template
					commTemplate = CommTemplate.CreateCommTemplate(0, (int)templateType, strName);

					// Set the template record
					commTemplate.Body = strBody;
					ent.CommTemplates.AddObject(commTemplate);

				}
				else
				{

					// Load the comm template
					commTemplate = (from ct in ent.CommTemplates
												 where ct.CommTemplateId == iCommTemplateId
												 select ct).First();

					// Update the template record
					commTemplate.Name = strName;
					commTemplate.Body = strBody;

				}

				// Track user actions
				UserAction.Session session = new UserAction.Session(iUserId, commTemplate, strName);

				// Save to database
				ent.SaveChanges();

				// Save user actions
				session.SaveChanges(ent);

			}
			catch (Exception x)
			{

				// Process error
				strError = ErrorProcessing.HandleException(x, "save template", iUserId);

			}

			// Return variable
			return strError;

		}

		public static string Set(DebtChasedEntities ent, int iCommTemplateId, string strName, string strFilepath, bool bReviewSummary, int iUserId)
		{

			// FOR LETTER TEMPLATES

			// Declare return variable
			string strError = null;

			// Get the summary line
			string strSummary = null;
			try
			{

				// If reviewing summary...
				if (bReviewSummary)
				{
					strSummary = WordSession.GetSummaryLine(strFilepath, CommTemplateListModel.SummaryLength + 20);
					if (strSummary != null)
						strSummary = CommTemplateListModel.MakeSummaryLine(strSummary, false);
				}

			}
			catch (Exception x)
			{

				// Process error
				strError = ErrorProcessing.HandleException(x, "summarise template", iUserId);
				//strSummary = null;

			}

			try
			{

				// Get filename
				string strFilename = Path.GetFileName(strFilepath);

				// If this is a new template...
				CommTemplate commTemplate = null;
				if (iCommTemplateId == 0)
				{

					// Load the comm template
					commTemplate = CommTemplate.CreateCommTemplate( 0, (int)Definitions.eCommTemplateType.Letter, strName );
					commTemplate.Filename = strFilename;
					commTemplate.SummaryLine = strSummary;
					ent.CommTemplates.AddObject(commTemplate);

				}
				else
				{

					// Load the comm template
					commTemplate = (from ct in ent.CommTemplates
												 where ct.CommTemplateId == iCommTemplateId
												 select ct).First();

					// Update the template record
					commTemplate.Name = strName;
					commTemplate.Filename = strFilename;
					if(bReviewSummary)
						commTemplate.SummaryLine = strSummary;

				}

				// Track user actions
				UserAction.Session session = new UserAction.Session(iUserId, commTemplate, strName);

				// Save to database
				ent.SaveChanges();

				// Save user actions
				session.SaveChanges(ent);

			}
			catch (Exception x)
			{

				// Process error
				strError = ErrorProcessing.HandleException(x, "save template", iUserId);

			}

			// Return variable
			return strError;

		}

		public static string ComposeNewTemplateFilename(string strExtension)
		{
#if DEBUG
			Debug.Assert( 
				(string.Compare(strExtension,".doc",true)==0)
				||
				(string.Compare(strExtension,".docx",true)==0)
			);
#endif // #if DEBUG
			
			// Compose filename
			return string.Format("DebtChasedTemplate-{0}{1}",Guid.NewGuid(),strExtension);

		}

	}

}
